//
// Copyright 2002-2004 Stottler Henke Associates, Inc.
// All Rights Reserved.
////////////////////////////////////////////////////////////////////////////////

package com.stottlerhenke.simbionic.engine.parser;

import com.stottlerhenke.simbionic.engine.SB_SingletonBook;
import com.stottlerhenke.simbionic.engine.file.SB_StreamReader;
import com.stottlerhenke.simbionic.api.*;
import com.stottlerhenke.simbionic.api.SB_Param;

/**
 * Variable containing a boolean value.
 */
public class SB_VarBoolean extends SB_Variable
{

  public SB_VarBoolean() {
    _parameterValue = new SB_Param(false);
  }
  public SB_VarBoolean(boolean value){
    _parameterValue = new SB_Param(value);
  }
  public SB_VarBoolean(SB_VarBoolean var2)
  throws SB_Exception
  {
    Copy(var2);
  }
  private void Copy(SB_VarBoolean var) 
  throws SB_Exception
  {
    _parameterValue = new SB_Param( var.GetValue() );
  }
  public void SetValue(boolean value){
    _parameterValue.setBoolean(value);
  }

  public void setSB_Param(SB_Param newParam) throws SB_Exception
  {
    newParam.getBoolean();
    
    _parameterValue = newParam;
  }
  
  public boolean GetValue()
  throws SB_Exception
  {
    return _parameterValue.getBoolean();
  }
  public SB_VarType GetType() { return SB_VarType.kBoolean; }
  
  public static boolean GET_BOOLEAN(SB_Variable var2)
  throws SB_Exception
  {
    return ((SB_VarBoolean)var2).GetValue();
  }
  public void load(SB_StreamReader reader,SB_SingletonBook book) throws SB_Exception
	{
    // this is really a pascal-style string
    String expr = reader.readPString();

    SB_Expression parsedExp = (SB_Expression)book.getParser().Parse(expr);

    // evaluating the expression without passing in an entity or execution frame is
    // only safe because the expression contains only constants!
    SB_Variable expValue = parsedExp.Evaluate(null,null);
    if (expValue.GetType() == SB_VarType.kBoolean)
    {
      SetValue( ((SB_VarBoolean)expValue).GetValue() );
    }
    else if (expValue.GetType() == SB_VarType.kInteger)
    {
      SetValue( ((SB_VarInteger)expValue).GetValue() != 0 );
    }
    else
      throw new SB_Exception("Illegal initial value " + expr + "for boolean variable.");
  }

  public SB_Variable opAssign(SB_VarBoolean var) 
  throws SB_Exception
  {
    if (this != var) {
      Copy(var);
    }
    return this;
  }

  public SB_Variable Clone() throws SB_Exception {
    return new SB_VarBoolean(this);
  }

  public SB_Variable opOr(SB_Variable arg2) throws SB_Exception {
    SB_Variable result = null;

    if(arg2.GetType() == SB_VarType.kBoolean)
      result = new SB_VarBoolean( GetValue() || GET_BOOLEAN(arg2) );
    return result;
  }
  public SB_Variable opAND(SB_Variable arg2) throws SB_Exception{
    SB_Variable result = null;

    if(arg2.GetType() == SB_VarType.kBoolean)
       result = new SB_VarBoolean( GetValue() && GET_BOOLEAN(arg2) );
    return result;
  }

  public SB_Variable opGRTEq(SB_Variable arg2) throws SB_Exception {
    //FATAL( false, "Invalid operation on boolean variable");
    return null;
  }

  public SB_Variable opLSSEq( SB_Variable arg2) throws SB_Exception  {
    //FATAL( false, "Invalid operation on boolean variable");
    return null;
  }

  public SB_Variable opNOTEq(SB_Variable arg2) throws SB_Exception{
    SB_Variable result = null;

    if(arg2.GetType() == SB_VarType.kBoolean)
       result = new SB_VarBoolean( GetValue() != GET_BOOLEAN(arg2) );
    else if(arg2.GetType() == SB_VarType.kInvalid)
       result = new SB_VarBoolean( true );
    return result;
  }

  public SB_Variable equals(SB_Variable arg2) throws SB_Exception {
    SB_Variable result = null;
    if(arg2.GetType() == SB_VarType.kBoolean)
      result = new SB_VarBoolean( GetValue() == GET_BOOLEAN(arg2) );
    else if(arg2.GetType() == SB_VarType.kInvalid)
      result = new SB_VarBoolean( false );

    return result;
  }

  public SB_Variable opGRT( SB_Variable arg2) throws SB_Exception  {
    //FATAL( false, "Invalid operation on boolean variable");
    return null;
  }

  public SB_Variable opLSS( SB_Variable arg2) throws SB_Exception  {
    //FATAL( false, "Invalid operation on boolean variable");
    return null;
  }

  public SB_Variable opMOD( SB_Variable arg2) throws SB_Exception  {
    //FATAL( false, "Invalid operation on boolean variable");
    return null;
  }

  public SB_Variable opEXP( SB_Variable arg2) throws SB_Exception  {
    //FATAL( false, "Invalid operation on boolean variable");
    return null;
  }

  public SB_Variable opDIV( SB_Variable arg2) throws SB_Exception  {
    //FATAL( false, "Invalid operation on boolean variable");
    return null;
  }

  public SB_Variable opMUL( SB_Variable arg2) throws SB_Exception  {
    //FATAL( false, "Invalid operation on boolean variable");
    return null;
  }

  public SB_Variable opSUB( SB_Variable arg2) throws SB_Exception  {
    //FATAL( false, "Invalid operation on boolean variable");
    return null;
  }

  public SB_Variable opADD( SB_Variable arg2) throws SB_Exception  {
    SB_Variable result = null;

    if(arg2.GetType() == SB_VarType.kString) // returns a concatenated string
    {
      String workStr;
      String tmp = (GetValue() ? "true" : "false");
      workStr = tmp + SB_VarString.GET_STRING(arg2);
      result = new SB_VarString( workStr );
     }
     return result;
  }

  public SB_Variable opNOT() throws SB_Exception  {
     return new SB_VarBoolean( !GetValue() );
  }

  public SB_Variable opNEG() throws SB_Exception  {
    //FATAL( false, "Invalid operation on boolean variable");
    return null;
  }

  public boolean bool() throws SB_Exception{
    return GetValue();
  }

  public String toString()
  {
    try
    {
    	return (GetValue() ? "true" : "false");
    }
    catch(SB_Exception ex)
    {
      return ex.toString();
    }
  }

}